/*
 Copyright 2011 and onwards Joao C. R. Pereira

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
*/

#ifndef JUMPTABLE_H
#define JUMPTABLE_H

#include "Types.h"

typedef struct JumpTableOnDiskStruct {

  unsigned bit000 : 1;
  unsigned bit001 : 1;
  unsigned bit002 : 1;
  unsigned bit003 : 1;
  unsigned bit004 : 1;
  unsigned bit005 : 1;
  unsigned bit006 : 1;
  unsigned bit007 : 1;
  unsigned bit008 : 1;
  unsigned bit009 : 1;
  unsigned bit010 : 1;
  unsigned bit011 : 1;
  unsigned bit012 : 1;
  unsigned bit013 : 1;
  unsigned bit014 : 1;
  unsigned bit015 : 1;
  unsigned bit016 : 1;
  unsigned bit017 : 1;
  unsigned bit018 : 1;
  unsigned bit019 : 1;
  unsigned bit020 : 1;
  unsigned bit021 : 1;
  unsigned bit022 : 1;
  unsigned bit023 : 1;
  unsigned bit024 : 1;
  unsigned bit025 : 1;
  unsigned bit026 : 1;
  unsigned bit027 : 1;
  unsigned bit028 : 1;
  unsigned bit029 : 1;
  unsigned bit030 : 1;
  unsigned bit031 : 1;
  unsigned bit032 : 1;
  unsigned bit033 : 1;
  unsigned bit034 : 1;
  unsigned bit035 : 1;
  unsigned bit036 : 1;
  unsigned bit037 : 1;
  unsigned bit038 : 1;
  unsigned bit039 : 1;
  unsigned bit040 : 1;
  unsigned bit041 : 1;
  unsigned bit042 : 1;
  unsigned bit043 : 1;
  unsigned bit044 : 1;
  unsigned bit045 : 1;
  unsigned bit046 : 1;
  unsigned bit047 : 1;
  unsigned bit048 : 1;
  unsigned bit049 : 1;
  unsigned bit050 : 1;
  unsigned bit051 : 1;
  unsigned bit052 : 1;
  unsigned bit053 : 1;
  unsigned bit054 : 1;
  unsigned bit055 : 1;
  unsigned bit056 : 1;
  unsigned bit057 : 1;
  unsigned bit058 : 1;
  unsigned bit059 : 1;
  unsigned bit060 : 1;
  unsigned bit061 : 1;
  unsigned bit062 : 1;
  unsigned bit063 : 1;
  unsigned bit064 : 1;
  unsigned bit065 : 1;
  unsigned bit066 : 1;
  unsigned bit067 : 1;
  unsigned bit068 : 1;
  unsigned bit069 : 1;
  unsigned bit070 : 1;
  unsigned bit071 : 1;
  unsigned bit072 : 1;
  unsigned bit073 : 1;
  unsigned bit074 : 1;
  unsigned bit075 : 1;
  unsigned bit076 : 1;
  unsigned bit077 : 1;
  unsigned bit078 : 1;
  unsigned bit079 : 1;
  unsigned bit080 : 1;
  unsigned bit081 : 1;
  unsigned bit082 : 1;
  unsigned bit083 : 1;
  unsigned bit084 : 1;
  unsigned bit085 : 1;
  unsigned bit086 : 1;
  unsigned bit087 : 1;
  unsigned bit088 : 1;
  unsigned bit089 : 1;
  unsigned bit090 : 1;
  unsigned bit091 : 1;
  unsigned bit092 : 1;
  unsigned bit093 : 1;
  unsigned bit094 : 1;
  unsigned bit095 : 1;
  unsigned bit096 : 1;
  unsigned bit097 : 1;
  unsigned bit098 : 1;
  unsigned bit099 : 1;
  unsigned bit100 : 1;
  unsigned bit101 : 1;
  unsigned bit102 : 1;
  unsigned bit103 : 1;
  unsigned bit104 : 1;
  unsigned bit105 : 1;
  unsigned bit106 : 1;
  unsigned bit107 : 1;
  unsigned bit108 : 1;
  unsigned bit109 : 1;
  unsigned bit110 : 1;
  unsigned bit111 : 1;
  unsigned bit112 : 1;
  unsigned bit113 : 1;
  unsigned bit114 : 1;
  unsigned bit115 : 1;
  unsigned bit116 : 1;
  unsigned bit117 : 1;
  unsigned bit118 : 1;
  unsigned bit119 : 1;
  unsigned bit120 : 1;
  unsigned bit121 : 1;
  unsigned bit122 : 1;
  unsigned bit123 : 1;
  unsigned bit124 : 1;
  unsigned bit125 : 1;
  unsigned bit126 : 1;
  unsigned bit127 : 1;
  unsigned bit128 : 1;
  unsigned bit129 : 1;
  unsigned bit130 : 1;
  unsigned bit131 : 1;
  unsigned bit132 : 1;
  unsigned bit133 : 1;
  unsigned bit134 : 1;
  unsigned bit135 : 1;
  unsigned bit136 : 1;
  unsigned bit137 : 1;
  unsigned bit138 : 1;
  unsigned bit139 : 1;
  unsigned bit140 : 1;
  unsigned bit141 : 1;
  unsigned bit142 : 1;
  unsigned bit143 : 1;
  unsigned bit144 : 1;
  unsigned bit145 : 1;
  unsigned bit146 : 1;
  unsigned bit147 : 1;
  unsigned bit148 : 1;
  unsigned bit149 : 1;
  unsigned bit150 : 1;
  unsigned bit151 : 1;
  unsigned bit152 : 1;
  unsigned bit153 : 1;
  unsigned bit154 : 1;
  unsigned bit155 : 1;
  unsigned bit156 : 1;
  unsigned bit157 : 1;
  unsigned bit158 : 1;
  unsigned bit159 : 1;
  unsigned bit160 : 1;
  unsigned bit161 : 1;
  unsigned bit162 : 1;
  unsigned bit163 : 1;
  unsigned bit164 : 1;
  unsigned bit165 : 1;
  unsigned bit166 : 1;
  unsigned bit167 : 1;
  unsigned bit168 : 1;
  unsigned bit169 : 1;
  unsigned bit170 : 1;
  unsigned bit171 : 1;
  unsigned bit172 : 1;
  unsigned bit173 : 1;
  unsigned bit174 : 1;
  unsigned bit175 : 1;
  unsigned bit176 : 1;
  unsigned bit177 : 1;
  unsigned bit178 : 1;
  unsigned bit179 : 1;
  unsigned bit180 : 1;
  unsigned bit181 : 1;
  unsigned bit182 : 1;
  unsigned bit183 : 1;
  unsigned bit184 : 1;
  unsigned bit185 : 1;
  unsigned bit186 : 1;
  unsigned bit187 : 1;
  unsigned bit188 : 1;
  unsigned bit189 : 1;
  unsigned bit190 : 1;
  unsigned bit191 : 1;
  unsigned bit192 : 1;
  unsigned bit193 : 1;
  unsigned bit194 : 1;
  unsigned bit195 : 1;
  unsigned bit196 : 1;
  unsigned bit197 : 1;
  unsigned bit198 : 1;
  unsigned bit199 : 1;
  unsigned bit200 : 1;
  unsigned bit201 : 1;
  unsigned bit202 : 1;
  unsigned bit203 : 1;
  unsigned bit204 : 1;
  unsigned bit205 : 1;
  unsigned bit206 : 1;
  unsigned bit207 : 1;
  unsigned bit208 : 1;
  unsigned bit209 : 1;
  unsigned bit210 : 1;
  unsigned bit211 : 1;
  unsigned bit212 : 1;
  unsigned bit213 : 1;
  unsigned bit214 : 1;
  unsigned bit215 : 1;
  unsigned bit216 : 1;
  unsigned bit217 : 1;
  unsigned bit218 : 1;
  unsigned bit219 : 1;
  unsigned bit220 : 1;
  unsigned bit221 : 1;
  unsigned bit222 : 1;
  unsigned bit223 : 1;
  unsigned bit224 : 1;
  unsigned bit225 : 1;
  unsigned bit226 : 1;
  unsigned bit227 : 1;
  unsigned bit228 : 1;
  unsigned bit229 : 1;
  unsigned bit230 : 1;
  unsigned bit231 : 1;
  unsigned bit232 : 1;
  unsigned bit233 : 1;
  unsigned bit234 : 1;
  unsigned bit235 : 1;
  unsigned bit236 : 1;
  unsigned bit237 : 1;
  unsigned bit238 : 1;
  unsigned bit239 : 1;
  unsigned bit240 : 1;
  unsigned bit241 : 1;
  unsigned bit242 : 1;
  unsigned bit243 : 1;
  unsigned bit244 : 1;
  unsigned bit245 : 1;
  unsigned bit246 : 1;
  unsigned bit247 : 1;
  unsigned bit248 : 1;
  unsigned bit249 : 1;
  unsigned bit250 : 1;
  unsigned bit251 : 1;
  unsigned bit252 : 1;
  unsigned bit253 : 1;
  unsigned bit254 : 1;
  unsigned bit255 : 1;

} JumpTableOnDisk;


typedef struct JumpTableInMemoryStruct {

  int jumps[256];
  byte lookup[256];
  int numJumps;

} JumpTableInMemory;


#define JumpTable_StoreDist(mem, dist) (mem)->jumps[dist-1]++
#define JumpTable_GetPosInTable(mem, dist) (mem)->lookup[dist-1]

void JumpTable_Clean(JumpTableInMemory * mem);
void JumpTable_Optimize(JumpTableInMemory * qmem);
void JumpTable_ToDisk(JumpTableInMemory * mem, JumpTableOnDisk * disk);
void JumpTable_ToMem(JumpTableOnDisk * disk, JumpTableInMemory * mem);

#endif /* JUMPTABLE_H */
